package cn.xetsoft.supermarket.dao.impl;

import cn.xetsoft.supermarket.common.Role;
import cn.xetsoft.supermarket.dao.UserDao;
import cn.xetsoft.supermarket.entity.User;
import cn.xetsoft.supermarket.util.JDBCUtils;
import lombok.extern.slf4j.Slf4j;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Vincent Vic
 * @since 2020/12/19 20:22
 * @version 1.0
 * @Description (User)表数据库访问层实现
 */
@Slf4j //使用lombok日志的注解
public class UserDaoImpl implements UserDao {

    /**
     * 通过ID查询单条数据
     * @param id 主键
     * @return User对象
     * @throws SQLException
     */
    @Override
    public User queryById(Integer id) throws SQLException {
        //获取连接 使用单例
        Connection conn = JDBCUtils.getInstanceConnection();
        //sql, 每行加空格
        String sql = "select * from  user where id=?";
        //预编译SQL，减少sql执行
        PreparedStatement ptmt = conn.prepareStatement(sql);
        //传参
        ptmt.setInt(1, id);
        //打印debug日志
        log.debug("run sql : {}",sql);
        log.debug("param -> {}",id);
        //执行
        ResultSet rs = ptmt.executeQuery();
        User user = null;
        while(rs.next()){
            user = new User();
            /**
             * 获取所有属性，设置到类中
             */
            resultDtoUser(rs, user);
        }
        return user;
    }

    @Override
    public User queryByUserName(String username) throws SQLException {
        //获取连接 使用单例
        Connection conn = JDBCUtils.getInstanceConnection();
        //sql, 每行加空格
        String sql = "select * from  user where username=?";
        //预编译SQL，减少sql执行
        PreparedStatement ptmt = conn.prepareStatement(sql);
        //传参
        ptmt.setString(1, username);
        //打印debug日志
        log.debug("run sql : {}",sql);
        log.debug("param -> {}",username);
        //执行
        ResultSet rs = ptmt.executeQuery();
        User user = null;
        while(rs.next()){
            user = new User();
            /**
             * 获取所有属性，设置到类中
             */
            resultDtoUser(rs, user);
        }
        return user;
    }

    /**
     * 查询全部
     * @return 对象列表
     */
    @Override
    public List<User> queryAll() throws SQLException {
        //获取连接 使用单例
        Connection conn = JDBCUtils.getInstanceConnection();
        //sql, 每行加空格
        String sql = "select * from  user";
        //预编译SQL，减少sql执行
        PreparedStatement ptmt = conn.prepareStatement(sql);
        //打印debug日志
        log.debug("run sql : {}",sql);
        //执行
        ResultSet rs = ptmt.executeQuery();
        List<User> users = new ArrayList<User>();
        while(rs.next()){
            User user = new User();
            /**
             * 获取所有属性，设置到类中
             */
            resultDtoUser(rs, user);
            //加入列表
            users.add(user);
        }

        return users;
    }

    /**
     * 登入操作
     * @param username 用户名
     * @param password 密码
     * @return 成功返回用户对象，失败为空
     */
    @Override
    public User login(String username, String password) throws SQLException {
        //获取连接 使用单例
        Connection conn = JDBCUtils.getInstanceConnection();
        //sql, 每行加空格
        String sql = "select * from  `user` where username=? AND `password`=?";
        //预编译SQL，减少sql执行
        PreparedStatement ptmt = conn.prepareStatement(sql);
        //传参
        ptmt.setString(1, username);
        ptmt.setString(2, password);
        //打印debug日志
        log.debug("run sql : {}",sql);
        log.debug("param -> {} , {}",username,password);
        //执行
        ResultSet rs = ptmt.executeQuery();
        User user = null;
        while(rs.next()){
            user = new User();
            /**
             * 获取所有属性，设置到类中
             */
            resultDtoUser(rs, user);
        }
        return user;
    }

    /**
     * 封装数据转移类
     * 从数据库结果转Userd对象
     * @param rs
     * @param user
     * @throws SQLException
     */
    private void resultDtoUser(ResultSet rs, User user) throws SQLException {
        //从结果中设置用户id
        user.setId(rs.getInt("id"));
        //从结果中设置用户名
        user.setUsername(rs.getString("username"));
        //从结果中获取密码
        user.setPassword(rs.getString("password"));
        //从结果中设置姓名
        user.setName(rs.getString("name"));
        //从结果中设置电话
        user.setPhone(rs.getString("phone"));
        //从结果中设置
        user.setFrequency(rs.getString("Frequency"));
        //从结果中转换到枚举类型
        user.setRole(Role.codeOf(rs.getInt("role")));
        //从结果中设置创建时间
        user.setCreateTime(rs.getDate("create_time"));
        //从结果中设置更新时间
        user.setUpdateTime(rs.getDate("update_time"));
    }

    /**
     * 新增用户数据
     * 新增用户是不能登入的，需要管理员授权为员工
     * @param user 实例对象
     * @return 影响行数
     */
    @Override
    public int insert(User user) throws SQLException {
        //获取连接 通过单例模式 懒汉获取连接
        Connection conn = JDBCUtils.getInstanceConnection();
        //sql
        String sql = "INSERT INTO `user`( username, `password`, `name`,phone,Frequency,role,create_time,update_time)"
                +"values("+"?,?,?,?,?,?,CURRENT_DATE(),CURRENT_DATE())";
        //预编译
        PreparedStatement ptmt = conn.prepareStatement(sql); //预编译SQL，减少sql执行

        //传参
        //共用封装
        userDtoParam(user, ptmt);

        //打印debug日志
        log.debug("run sql : {}",sql);
        log.debug("param -> {}",user);
        //执行并返回结果
        return ptmt.executeUpdate();
    }

    /**
     * 部分共用封装
     */
    private void userDtoParam(User user, PreparedStatement ptmt) throws SQLException {
        //设置用户名
        ptmt.setString(1, user.getUsername());
        //设置密码
        ptmt.setString(2, user.getPassword());
        //设置姓名
        ptmt.setString(3, user.getName());
        //设置手机号
        ptmt.setString(4, user.getPhone());
        //设置排版信息 初始化未排版
        ptmt.setString(5, user.getFrequency());
        //设置初始化为没有权限，需要管理员或者超级管理员赋值
        ptmt.setInt(6, user.getRole().getCode());
    }

    /**
     * 修改数据
     *
     * @param user 实例对象
     * @return 影响行数
     */
    @Override
    public int update(User user) throws SQLException {
        //获取连接
        Connection conn = JDBCUtils.getInstanceConnection();
        //sql, 每行加空格
        String sql = "UPDATE `user`" +
                " set username=?, `password`=?, `name`=?,phone=?,Frequency=?,role=?,update_time = CURRENT_DATE()"+
                " where id=?";
        //预编译
        PreparedStatement ptmt = conn.prepareStatement(sql); //预编译SQL，减少sql执行

        //传参
        //部分共用封装
        userDtoParam(user, ptmt);
        //设置条件id
        ptmt.setInt(7,user.getId());
        //打印debug日志
        log.debug("run sql : {}",sql);
        log.debug("param -> {}",user);
        //执行
        return ptmt.executeUpdate();
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 影响行数
     */
    @Override
    public int deleteById(Integer id) throws SQLException {
        //获取连接
        Connection conn = JDBCUtils.getInstanceConnection();
        //sql, 每行加空格
        String sql = "delete from `user` where id=?";
        //预编译SQL，减少sql执行
        PreparedStatement ptmt = conn.prepareStatement(sql);

        //传参
        ptmt.setInt(1, id);

        //打印debug日志
        log.debug("run sql : {}",sql);
        log.debug("param -> {}",id);

        //执行
        return ptmt.executeUpdate();
    }
}
